home *** CD-ROM | disk | FTP | other *** search
/ Explore the World of Software 2 / Explore the World of Software 2.iso / atm / winfont3 / fontangl.c < prev    next >
C/C++ Source or Header  |  1987-10-28  |  15KB  |  538 lines

  1. #include "windows.h"
  2. #include "fontangl.h"
  3.  
  4. /*  Sample Angled Font Manipulation Module
  5.  */
  6.  
  7. extern long FAR PASCAL lstrlen();
  8. extern long FAR PASCAL lstrcpy();
  9. extern long FAR PASCAL lstrcat();
  10.  
  11. int yCoord;         /* the y coordinate of the starting text */
  12. int nFirstIndex;    /* the font currently displayed at the top */
  13. int nLastIndex;     /* the font currently displayed at the bottom */
  14. int nTopClipped;    /* the clipped portion of the top line of text */
  15. int nBottomClipped; /* the clipped portion of the bottom line of text */
  16. int nScrollBarTop;  /* the nLastIndex at which the scrollbar is at the top */
  17. int nFontCount;     /* number of fonts enumerated */
  18. HFONT hFontANSIFIXED;
  19.  
  20. HBRUSH hbrWhite;
  21. HBRUSH hbrBlack;
  22. HBRUSH hbrGray;
  23.  
  24. char    szName[ LF_FACESIZE + 10 ];
  25.  
  26. /* Save away all enumerated LogFonts and TextMetrics */
  27. LOGFONT LF[ MAXFONTS ];
  28. TEXTMETRIC TM[ MAXFONTS ];
  29.  
  30. /* the two callback routines */
  31. static FARPROC eafproc;
  32. static FARPROC cbproc;
  33.  
  34. typedef struct {
  35.     HDC     hDC;
  36.     FARPROC lpCallbackFunc;
  37. } EAFDataType;
  38.  
  39.  
  40. MyCopyStruct( dst, src, size )
  41. PSTR dst;
  42. LPSTR src;
  43. int size;
  44. {
  45.     while (size--)
  46.         *dst++ = *src++;
  47. }
  48.  
  49.  
  50. BOOL MyCompStruct( pS1, pS2, size )
  51. BYTE *pS1;
  52. BYTE *pS2;
  53. int size;
  54. {
  55.     while (size--)
  56.         if (*pS1++ != *pS2++)
  57.             return FALSE;
  58.     return TRUE;
  59. }
  60.  
  61.  
  62. EnumAllFonts( hWnd, lpCallbackFunc )
  63. HWND hWnd;
  64. FARPROC lpCallbackFunc;
  65. {
  66.     HDC hDC;
  67.     EAFDataType EAFData;
  68.  
  69.     nFontCount = 0;
  70.     hDC = GetDC( hWnd );
  71.  
  72.     (EAFData.hDC)            = hDC;
  73.     (EAFData.lpCallbackFunc) = lpCallbackFunc;
  74.  
  75.     /* Enumerates one font from each facename */
  76.  
  77.     EnumFonts( hDC, (LPSTR)NULL, eafproc, (LPSTR)&EAFData );
  78.  
  79.     ReleaseDC( hWnd, hDC );
  80. }
  81.  
  82.  
  83. short int FAR PASCAL EAFCallback( lpLogFont, lpTextMetrics, FontType, lpEAFData )
  84. LOGFONT FAR *lpLogFont;
  85. TEXTMETRIC FAR *lpTextMetrics;
  86. WORD FontType;
  87. EAFDataType FAR *lpEAFData;
  88. {
  89.     /* Enumerates all fonts with the same facename */
  90.  
  91.     return( EnumFonts( lpEAFData->hDC,
  92.                        (LPSTR)lpLogFont->lfFaceName,
  93.                        lpEAFData->lpCallbackFunc,
  94.                        (LPSTR)NULL ) );
  95. }
  96.  
  97.  
  98. short int FAR PASCAL cb( lpLogfont, lpTextMetrics, nFontType, lpData )
  99. LPLOGFONT lpLogfont;
  100. LPTEXTMETRIC lpTextMetrics;
  101. WORD nFontType;
  102. LONG lpData;
  103. {
  104.  
  105.     /* Skip over any raster fonts. We only want vector fonts. */
  106.     /* ################################################################### */
  107.     if ( nFontType & RASTER_FONTTYPE ) return TRUE;
  108.  
  109.     MyCopyStruct( (PSTR)&LF[nFontCount], (LPSTR)lpLogfont, sizeof(LOGFONT) );
  110.     MyCopyStruct( (PSTR)&TM[nFontCount], (LPSTR)lpTextMetrics, sizeof(TEXTMETRIC) );
  111.  
  112.     /* Stop callback when we can't hold anymore */
  113.  
  114.     if (++nFontCount == MAXFONTS)
  115.         return FALSE;
  116.     else
  117.         return TRUE;
  118. }
  119.  
  120.  
  121. /* ######################################################################### */
  122. DWORD PlaceFont( hDC, x, y, pLogfont )
  123. HDC hDC;
  124. short x, y;
  125. LOGFONT *pLogfont;
  126. {
  127.     HFONT hLocalFont;
  128.     DWORD   Extent;
  129.  
  130.     hLocalFont = CreateFontIndirect( (LPLOGFONT)pLogfont );
  131.     SelectObject( hDC, (HANDLE)hLocalFont );
  132.  
  133.     TextOut( hDC,
  134.              x, y,
  135.              (LPSTR)szName,
  136.              lstrlen((LPSTR)szName) );
  137.  
  138.     Extent = GetTextExtent(hDC,
  139.                            (LPSTR)szName,
  140.                            lstrlen((LPSTR)szName) );
  141.  
  142.     /* Blow away the memory allocated for the font */
  143.  
  144.     SelectObject( hDC, hFontANSIFIXED );
  145.     DeleteObject( hLocalFont );
  146.  
  147.     return ( Extent );
  148. }
  149.  
  150.  
  151. #define OPB() \
  152.     TextOut( hDC, CurX, CurY, (LPSTR)Buffer, Chars ); \
  153.     CurY += TextMetric.tmHeight + TextMetric.tmExternalLeading;
  154.  
  155.  
  156. ShowFont( hDC, i, y, WindowWidth )
  157. HDC hDC;
  158. int i;          /* index into LF and TM */
  159. int y;
  160. int WindowWidth;
  161. {
  162.     LOGFONT *pLogfont;
  163.     short   CurX, CurY;
  164.     DWORD   Extent;
  165.     short   OldBkMode;
  166.     short   Angle;
  167.     char    Buffer[256];
  168.     short   Chars;
  169.     TEXTMETRIC  TextMetric;
  170.  
  171.     OldBkMode = SetBkMode( hDC, TRANSPARENT );
  172.  
  173.     pLogfont = &(LF[i]);
  174.  
  175.     GetTextMetrics( hDC, &TextMetric );
  176.  
  177.     CurX = TextMetric.tmAveCharWidth;
  178.     CurY = y;
  179.  
  180.     Chars = sprintf(Buffer, "lfCharSet       = %d",
  181.                    pLogfont->lfCharSet      ); OPB();
  182.     Chars = sprintf(Buffer, "lfOutPrecision  = %d",
  183.                    pLogfont->lfOutPrecision ); OPB();
  184.     Chars = sprintf(Buffer, "lfClipPrecision = %d",
  185.                    pLogfont->lfClipPrecision); OPB();
  186.  
  187.     CurX = ( TextMetric.tmAveCharWidth + WindowWidth ) / 2;
  188.     CurY = y;
  189.  
  190.     Chars = sprintf(Buffer, "lfQuality             = %d",
  191.                    pLogfont->lfQuality             ); OPB();
  192.     Chars = sprintf(Buffer, "lfPitchAndFamily&0x03 = %d",
  193.                    pLogfont->lfPitchAndFamily&0x03 ); OPB();
  194.     Chars = sprintf(Buffer, "lfPitchAndFamily&0xF0 = %d",
  195.                    pLogfont->lfPitchAndFamily&0xF0 ); OPB();
  196.  
  197.     lstrcpy( (LPSTR)szName, (LPSTR)"  " );
  198.     lstrcat( (LPSTR)szName, (LPSTR)pLogfont->lfFaceName );
  199.  
  200.     CurX = TM[i].tmAveCharWidth;
  201.     CurY = y;
  202.  
  203.     pLogfont->lfEscapement  = 3600-900;
  204.     pLogfont->lfOrientation = 0;
  205.     Extent = PlaceFont( hDC, CurX, CurY, pLogfont );
  206.  
  207.     CurX += ( LOWORD(Extent) + WindowWidth ) / 2;
  208.     CurY += (HIWORD(Extent) - CHARHEIGHT( i ));
  209.  
  210.     for (Angle = 0; Angle <= 1800; Angle += 225) {
  211.         pLogfont->lfEscapement  = pLogfont->lfOrientation = Angle;
  212.         PlaceFont( hDC, CurX, CurY, pLogfont );
  213.     }
  214.  
  215.     pLogfont->lfEscapement  = 0;
  216.     pLogfont->lfOrientation = 0;
  217.     SetBkMode( hDC, OldBkMode );
  218. }
  219. /* ######################################################################### */
  220.  
  221.  
  222. LONG FontAnglPaint( hDC, nRepaintBegin, nRepaintEnd, WindowWidth )
  223. HDC hDC;
  224. int nRepaintBegin, nRepaintEnd;
  225. int WindowWidth;
  226. {
  227.     int i, y, h;
  228.  
  229.     /* Convert the nRepaintBegin line to a font index */
  230.  
  231.     i = nFirstIndex;
  232.     y = -nTopClipped;
  233.     h = 0;
  234.     do {
  235.         y += h;
  236.         h = STRINGHEIGHT(i);
  237.         i++;
  238.     } while ( (i < nFontCount) && ( (y + h) < nRepaintBegin ));
  239.  
  240.     /* Backtrack since we passed it */
  241.  
  242.     i--;
  243.  
  244.     /* Repaint until we pass the nRepaintEnd line */
  245.  
  246.     for (; (i < nFontCount) && (y < nRepaintEnd); i++) {
  247.         ShowFont( hDC, i, y, WindowWidth );
  248.         y += STRINGHEIGHT(i);
  249.         }
  250.  
  251.     /* Return the last displayed font index and its clipped amount */
  252.  
  253.     h = y - nRepaintEnd;
  254.     return( MAKELONG( i-1, (h<0 ? 0 : h) ) );
  255. }
  256.  
  257.  
  258. int FontAnglScroll( hWnd, cmd )
  259. HWND hWnd;
  260. int cmd;
  261. {
  262.     int samount, sm, h;
  263.  
  264.     switch( cmd )
  265.     {
  266.     case SB_LINEDOWN:
  267.         if ((nLastIndex < nFontCount-1) || nBottomClipped) {
  268.  
  269.             /* Figure out how much to scroll up:
  270.              *   Reveal the bottom row if some part of it was hidded,
  271.              *   otherwise bring in the next row.
  272.              */
  273.  
  274.             if (nBottomClipped)
  275.                 sm = nBottomClipped;
  276.             else {
  277.                 nLastIndex++;
  278.                 sm = STRINGHEIGHT(nLastIndex);
  279.                 }
  280.             samount = sm;
  281.             nBottomClipped = 0;
  282.  
  283.             /* Move up enough rows to reveal the scroll amount */
  284.  
  285.             h = STRINGHEIGHT(nFirstIndex) - nTopClipped;
  286.             while ( (sm-=h) >= 0 ) {
  287.                 nFirstIndex++;
  288.                 h = STRINGHEIGHT(nFirstIndex);
  289.                 }
  290.  
  291.             /* Clip the top row with the remaining pixels */
  292.  
  293.             if (sm)
  294.                 nTopClipped = STRINGHEIGHT(nFirstIndex) + sm;
  295.             else
  296.                 nTopClipped = 0;
  297.  
  298.             /* Scroll up */
  299.  
  300.             ScrollWindow( hWnd,
  301.                           0,
  302.                           -samount,
  303.                           (LPRECT)NULL,
  304.                           (LPRECT)NULL );
  305.             SetScrollPos( hWnd, SB_VERT, nLastIndex-nScrollBarTop, TRUE );
  306.             }
  307.         break;
  308.  
  309.     case SB_LINEUP:
  310.         if (nFirstIndex || nTopClipped) {
  311.  
  312.             /* Figure out how much to scroll down */
  313.  
  314.             if (nTopClipped)
  315.                 sm = nTopClipped;
  316.             else {
  317.                 nFirstIndex--;
  318.                 sm = STRINGHEIGHT(nFirstIndex);
  319.                 }
  320.             samount = sm;
  321.             nTopClipped = 0;
  322.  
  323.             /* Move down enough rows to make top row completely visible */
  324.  
  325.             h = STRINGHEIGHT(nLastIndex) - nBottomClipped;
  326.             while ( (sm-=h) >= 0 ) {
  327.                 nLastIndex--;
  328.                 h = STRINGHEIGHT(nLastIndex);
  329.                 }
  330.  
  331.             /* Figure out clipped amount as result of scrolling */
  332.  
  333.             if (sm)
  334.                 nBottomClipped = STRINGHEIGHT(nLastIndex) + sm;
  335.             else
  336.                 nBottomClipped = 0;
  337.  
  338.             /* Scroll down */
  339.  
  340.             ScrollWindow( hWnd,
  341.                           0,
  342.                           samount,
  343.                           (LPRECT)NULL,
  344.                           (LPRECT)NULL );
  345.             SetScrollPos( hWnd, SB_VERT, nLastIndex-nScrollBarTop, TRUE );
  346.             }
  347.         break;
  348.     }
  349. }
  350.  
  351.  
  352. int FontAnglSize( hWnd, width, length )
  353. HWND hWnd;
  354. int width, length;
  355. {
  356.     static int oldlength = 0;
  357.  
  358.     /* Redraw completely if vertical position changed:  avoid the
  359.      *                                 -----    -----
  360.      * case where tiling changes from  |---| to | | | and the last
  361.      *                                 -----    -----
  362.      * font is displayed at the bottom.
  363.      */
  364.  
  365.     if (length != oldlength) {
  366.         nFirstIndex = 0;
  367.         nTopClipped = 0;
  368.         oldlength = length;
  369.         }
  370. }
  371.  
  372.  
  373. int FontAnglCommand( hWnd, cmd )
  374. HWND hWnd;
  375. WORD cmd;
  376. {
  377.     if (cmd == START_SESSION) {
  378.         EnumAllFonts( hWnd, cbproc );
  379.         nFirstIndex = 0;
  380.         nTopClipped = 0;
  381.         InvalidateRect( hWnd, (LPRECT)NULL, TRUE );
  382.         UpdateWindow( hWnd );
  383.         }
  384. }
  385.  
  386.  
  387. long FAR PASCAL FontAnglWndProc( hWnd, message, wParam, lParam )
  388. HWND hWnd;
  389. unsigned message;
  390. WORD wParam;
  391. LONG lParam;
  392. {
  393.     PAINTSTRUCT ps;
  394.     RECT rcEntire;
  395.     int i;
  396.     LONG l;
  397.  
  398.     switch (message)
  399.     {
  400.     case WM_DESTROY:
  401.         PostQuitMessage( 0 );
  402.         break;
  403.  
  404.     case WM_COMMAND:
  405.         FontAnglCommand( hWnd, wParam );
  406.         break;
  407.  
  408.     case WM_PAINT:
  409.         GetClientRect( hWnd, (LPRECT)&rcEntire );
  410.         BeginPaint( hWnd, (LPPAINTSTRUCT)&ps );
  411.         l = FontAnglPaint( ps.hdc,
  412.                            ps.rcPaint.top,
  413.                            ps.rcPaint.bottom,
  414.                            rcEntire.right - rcEntire.left );
  415.  
  416.         /* If the whole client rectangle is repainted, remember the index
  417.          * of the last font displayed, and if it was clipped at the bottom.
  418.          * This info helps in scrolling.
  419.          */
  420.  
  421.         if (nFontCount &&
  422.             MyCompStruct( (BYTE *)&(ps.rcPaint), (BYTE *)&rcEntire, sizeof(RECT)))
  423.             {
  424.             nLastIndex = LOWORD( l );
  425.             nBottomClipped = HIWORD( l );
  426.  
  427.             /* Redefine scrollbar if redrew from the top */
  428.  
  429.             if (nFirstIndex==0) {
  430.                 nScrollBarTop = nLastIndex;
  431.                 i = (nFontCount-1)-nScrollBarTop;
  432.                 if (i<=0) {
  433.                     if (nBottomClipped)
  434.                         SetScrollRange( hWnd, SB_VERT, 0, 1, FALSE );
  435.                     else
  436.                         /* No need to scroll */
  437.                         SetScrollRange( hWnd, SB_VERT, 0, 32767, FALSE );
  438.                     }
  439.                 else
  440.                     SetScrollRange( hWnd, SB_VERT, 0, i, FALSE );
  441.                 SetScrollPos( hWnd, SB_VERT, 0, TRUE );
  442.                 }
  443.             }
  444.         EndPaint( hWnd, (LPPAINTSTRUCT)&ps );
  445.         break;
  446.  
  447.     case WM_SIZE:
  448.         FontAnglSize( hWnd, LOWORD(lParam), HIWORD(lParam) );
  449.         break;
  450.  
  451.     case WM_VSCROLL:
  452.         FontAnglScroll( hWnd, wParam );
  453.         break;
  454.  
  455.     default :
  456.         return (DefWindowProc( hWnd, message, wParam, lParam));
  457.         break;
  458.     }
  459.     return(0L);
  460. }
  461.  
  462.  
  463. FontAnglInit( hInstance )
  464. HANDLE hInstance;
  465. {
  466.     PWNDCLASS   pFontAnglClass;
  467.  
  468.     /* Set up some default brushes */
  469.  
  470.     hbrWhite = GetStockObject( WHITE_BRUSH );
  471.     hbrBlack = GetStockObject( BLACK_BRUSH );
  472.     hbrGray  = GetStockObject( GRAY_BRUSH );
  473.     hFontANSIFIXED = GetStockObject ( ANSI_FIXED_FONT );
  474.  
  475.     /* Allocate class structure in local heap */
  476.  
  477.     pFontAnglClass = (PWNDCLASS)LocalAlloc( LPTR, sizeof(WNDCLASS) );
  478.     pFontAnglClass->hIcon         = LoadIcon( hInstance,(LPSTR)"fontangl" );
  479.     pFontAnglClass->hCursor       = LoadCursor( NULL, IDC_ARROW );
  480.     pFontAnglClass->lpszMenuName  = (LPSTR)"fontAngl";
  481.     pFontAnglClass->lpszClassName = (LPSTR)"FontAngl";
  482.     pFontAnglClass->hbrBackground = (HBRUSH)hbrWhite;
  483.     pFontAnglClass->style         = CS_HREDRAW | CS_VREDRAW;
  484.     pFontAnglClass->lpfnWndProc   = FontAnglWndProc;
  485.     pFontAnglClass->hInstance     = hInstance;
  486.  
  487.     if (!RegisterClass( (LPWNDCLASS)pFontAnglClass ) )
  488.         return FALSE;
  489.  
  490.     LocalFree( (HANDLE)pFontAnglClass );
  491.     return TRUE;    /* Initialization succeeded */
  492. }
  493.  
  494.  
  495. int PASCAL WinMain( hInstance, hPrev, lpszCmdLine, cmdShow )
  496. HANDLE hInstance, hPrev;
  497. LPSTR lpszCmdLine;
  498. int cmdShow;
  499. {
  500.     MSG msg;
  501.     HWND hWnd;
  502.  
  503.     if (!hPrev) {
  504.         if ( !FontAnglInit(hInstance) )
  505.             return( FALSE );
  506.         }
  507.     else {
  508.         GetInstanceData( hPrev, (PSTR)&hFontANSIFIXED, sizeof( HFONT ) );
  509.         GetInstanceData( hPrev, (PSTR)&hbrWhite, sizeof( hbrWhite ) );
  510.         GetInstanceData( hPrev, (PSTR)&hbrBlack, sizeof( hbrBlack ) );
  511.         GetInstanceData( hPrev, (PSTR)&hbrGray,  sizeof( hbrGray ) );
  512.         }
  513.  
  514.     hWnd = (HWND)CreateWindow(
  515.         (LPSTR) "FontAngl",
  516.         (LPSTR) "Angled Fonts",
  517.         WS_TILEDWINDOW | WS_VSCROLL,
  518.         0, 0, 0, 100,
  519.         (HANDLE)NULL,
  520.         (HANDLE)NULL,
  521.         (HANDLE)hInstance,
  522.         (HANDLE)NULL
  523.         );
  524.  
  525.     eafproc = MakeProcInstance( (FARPROC)EAFCallback, hInstance );
  526.     cbproc  = MakeProcInstance( (FARPROC)cb, hInstance );
  527.  
  528.     ShowWindow(hWnd, cmdShow);
  529.     UpdateWindow( hWnd );
  530.  
  531.     while (GetMessage((LPMSG)&msg, NULL, 0, 0)) {
  532.         TranslateMessage((LPMSG)&msg);
  533.         DispatchMessage((LPMSG)&msg);
  534.         }
  535.  
  536.     return msg.wParam;
  537. }
  538.